
import java.util.Date;
import java.text.SimpleDateFormat;

class TceController {

    SolicitacaoService solicitacaoService;
    TceService tceService;
    CursoService cursoService;

    /*
     * Closure que lista os TCEs.
    */
    def list   = {
        if (!verificaLogon()) {
            return;
        }
        params.max = Math.min(params.max ? params.int('max') : 10, 100);
        [tceInstanceList: Tce.list(params), tceInstanceTotal: Tce.count()]
    }

    /*
     * Closure que carrega a tela de cadastro
     */
    def create = {
        if (!verificaLogon()) {
            return;
        }

        def tceInstance   = new Tce();
        def solicitacao = Solicitacao.findById(params.id)
        Vaga vaga = Vaga.findById(solicitacao.vaga.id);
        def cursoInstance = Curso.executeQuery("SELECT cu FROM Curso cu, Formacao fo WHERE cu.id = fo.curso.id AND fo.estagiario.id = ?",[solicitacao.estagiario.id]);
        def IEInstance    = InstituicaoEnsino.executeQuery("SELECT ie FROM InstituicaoEnsino ie, Formacao fo WHERE ie.id = fo.instituicaoEnsino.id AND fo.estagiario.id = ?",[solicitacao.estagiario.id]);
        tceInstance.solicitacao = solicitacao;
        tceInstance.atividades  = vaga.atribuicoes;
        tceInstance.chSemanal   = vaga.chSemanal;
        tceInstance.remunera    = vaga.remuneracao;
        tceInstance.sequencia   = tceService.verificaProximaSequenciaTce(solicitacao);
        return [tceInstance       : tceInstance,
                cursoInstance     : cursoInstance,
                instituicaoEnsino : IEInstance];
    }


    /*
     * Closure que recebe os dados do formulário e grava.
     */
    def save   = {
        if (!verificaLogon()) {
            return;
        }
        def tceInstance = new Tce(params);
        Solicitacao solicitacao = Solicitacao.get(params.solicitacao.id)
        def cursoInstance = Curso.executeQuery("SELECT cu FROM Curso cu, Formacao fo WHERE cu.id = fo.curso.id AND fo.estagiario.id = ?",[solicitacao.estagiario.id]);
        def IEInstance    = InstituicaoEnsino.executeQuery("SELECT ie FROM InstituicaoEnsino ie, Formacao fo WHERE ie.id = fo.instituicaoEnsino.id AND fo.estagiario.id = ?",[solicitacao.estagiario.id]);

        // Verifica se a carga horária é compativel com a formação.
        if(cursoService.verificaCargaHorariaCursoVaga(Curso.findById(tceInstance.curso.id), Vaga.findById(solicitacao.vaga.id), Estagiario.findById(solicitacao.estagiario.id))){
            // Calcula da data final do tce apartir da data inicial.
            tceInstance.dtFim = tceService.calculaDataFimTce(params.dtInicio);
            // Grava o TCE.
            if (tceInstance.save(flush: true)) {
                // Muda o situacao da solicitacao para "Liberada".
                solicitacaoService.liberarSolicitacao(solicitacao)
                flash.message = "TCE criado com sucesso!";
                redirect(action: "edit", id: tceInstance.id);
            }else {
                render(view:"create",model: [tceInstance       : tceInstance,
                                             cursoInstance     : cursoInstance,
                                             instituicaoEnsino : IEInstance]);
            }
        }else{
            flash.message = "A carga horária não é compatível com a sua formação do Estagiário.<br/> Formação EJA só pode trabalhar 20h semanais.";
            render(view:"create",model: [tceInstance       : tceInstance,
                                         cursoInstance     : cursoInstance,
                                         instituicaoEnsino : IEInstance]);
        }
    };

    /*
     * Closure que carrega os dados para tela de edição.
     */
    def edit   = {
        if (!verificaLogon()) {
            return;
        }
        int totalRemunera;
        int totalPagamento;
        int totalPlanoEstagio;
        
        def tceInstance = Tce.findById(params.id);
        Solicitacao solicitacao = Solicitacao.get(tceInstance.solicitacao.id)
        def cursoInstance = Curso.executeQuery("SELECT cu FROM Curso cu, Formacao fo WHERE cu.id = fo.curso.id AND fo.estagiario.id = ?",[solicitacao.estagiario.id]);
        def IEInstance    = InstituicaoEnsino.executeQuery("SELECT ie FROM InstituicaoEnsino ie, Formacao fo WHERE ie.id = fo.instituicaoEnsino.id AND fo.estagiario.id = ?",[solicitacao.estagiario.id]);

        // REMUNERAÇÃO.
        // Carrega os dados para a alteração.
        def tceRemuneraDadosInstance = '';
        if(params.remunerar != null){
            tceRemuneraDadosInstance = TceRemunera.findById(params.remunerar);
        }else{
            tceRemuneraDadosInstance = new TceRemunera();
        }
        // Carrega os endereços cadastrados.
        def tceRemuneraInstance   = TceRemunera.findAllByTce(tceInstance);
        if (tceRemuneraInstance != null){
            totalRemunera = tceRemuneraInstance.count();
        }else{
            tceRemuneraInstance   = new TceRemunera();
        }

        // PAGAMENTO.
        // Carrega os dados para a alteração.
        def tcePagamentoDadosInstance = '';
        if(params.pagamento != null){
            tcePagamentoDadosInstance = TcePagamento.findById(params.pagamento);
        }else{
            tcePagamentoDadosInstance = new TcePagamento();
        }
        // Carrega os endereços cadastrados.
        def tcePagamentoInstance   = TcePagamento.findAllByTce(tceInstance);
        if (tcePagamentoInstance != null){
            totalPagamento = tcePagamentoInstance.count();
        }else{
            tcePagamentoInstance   = new TcePagamento();
        }
        // FORMA PAGAMENTO
        def formaPagamentoInstance = FormaPagamento.findAll();

        // PLANO DE ESTÁGIO.
        // Carrega os dados para a alteração.
        def planoEstagioDadosInstance = '';
        if(params.plano != null){
            planoEstagioDadosInstance = PlanoEstagio.findById(params.plano);
        }else{
            planoEstagioDadosInstance = new PlanoEstagio();
        }
        // Carrega os endereços cadastrados.
        def planoEstagioInstance   = PlanoEstagio.findAllByTce(tceInstance);
        if (planoEstagioInstance != null){
            totalPlanoEstagio = planoEstagioInstance.count();
        }else{
            planoEstagioInstance   = new PlanoEstagio();
        }

        //envia os dados para tela.
        if (tceInstance){
            return [tceInstance               : tceInstance,
                    cursoInstance             : cursoInstance,
                    instituicaoEnsino         : IEInstance,
                    tceRemuneraInstance       : tceRemuneraDadosInstance,
                    tceRemuneraInstanceList   : tceRemuneraInstance,
                    tceRemuneraInstanceTotal  : totalRemunera,
                    tcePagamentoInstance      : tcePagamentoDadosInstance,
                    tcePagamentoInstanceList  : tcePagamentoInstance,
                    tcePagamentoInstanceTotal : totalPagamento,
                    formaPagamentoInstance    : formaPagamentoInstance,
                    planoEstagioInstance      : planoEstagioDadosInstance,
                    planoEstagioInstanceList  : planoEstagioInstance,
                    planoEstagioInstanceTotal : totalPlanoEstagio];
        }else {
            flash.message="TCE não encontrado!";
            redirect(action: "create");
        }

    };


    /*
     * Closure que grava as alterações.
     */
    def update   = {
        if (!verificaLogon()) {
            return;
        }
        int totalRemunera;
        int totalPagamento;
        int totalPlanoEstagio;
        // carrega os dados
        def tceInstance = Tce.get(params.id);
        if(tceService.verificaSituacaoTce(tceInstance) == 'aguardando'){
            Solicitacao solicitacao = Solicitacao.get(tceInstance.solicitacao.id)
            def cursoInstance = Curso.executeQuery("SELECT cu FROM Curso cu, Formacao fo WHERE cu.id = fo.curso.id AND fo.estagiario.id = ?",[solicitacao.estagiario.id]);
            def IEInstance    = InstituicaoEnsino.executeQuery("SELECT ie FROM InstituicaoEnsino ie, Formacao fo WHERE ie.id = fo.instituicaoEnsino.id AND fo.estagiario.id = ?",[solicitacao.estagiario.id]);
            // REMUNERAÇÃO.
            // Carrega os endereços cadastrados.
            def tceRemuneraInstance   = TceRemunera.findAllByTce(tceInstance);
            if (tceRemuneraInstance != null){
                totalRemunera = tceRemuneraInstance.count();
            }else{
                tceRemuneraInstance   = new TceRemunera();
            }

            // PAGAMENTO.
            // Carrega os endereços cadastrados.
            def tcePagamentoInstance   = TcePagamento.findAllByTce(tceInstance);
            if (tcePagamentoInstance != null){
                totalPagamento = tcePagamentoInstance.count();
            }else{
                tcePagamentoInstance   = new TcePagamento();
            }
            // FORMA PAGAMENTO
            def formaPagamentoInstance = FormaPagamento.findAll();

            // PLANO DE ESTÁGIO.
            // Carrega os endereços cadastrados.
            def planoEstagioInstance   = PlanoEstagio.findAllByTce(tceInstance);
            if (planoEstagioInstance != null){
                totalPlanoEstagio = planoEstagioInstance.count();
            }else{
                planoEstagioInstance   = new PlanoEstagio();
            }
            tceInstance.properties = params;
            tceInstance.dtFim = tceService.calculaDataFimTce(params.dtInicio);
            if(tceInstance.save(flush: true)){
                flash.message = "TCE atualizado com sucesso.";
                redirect(action: "edit", id: tceInstance.id);
            }else {
                flash.message = "Não foi possível atualizar o TCE.";
                render(view:"edit",model: [tceInstance               : tceInstance,
                                           cursoInstance             : cursoInstance,
                                           instituicaoEnsino         : IEInstance,
                                           tceRemuneraInstanceList   : tceRemuneraInstance,
                                           tceRemuneraInstanceTotal  : totalRemunera,
                                           tcePagamentoInstanceList  : tcePagamentoInstance,
                                           tcePagamentoInstanceTotal : totalPagamento,
                                           formaPagamentoInstance    : formaPagamentoInstance,
                                           planoEstagioInstanceList  : planoEstagioInstance,
                                           planoEstagioInstanceTotal : totalPlanoEstagio]);
            }
        }else{
            flash.message = "TCE só pode ser alterado com situcao aguardando.";
            redirect(action: "edit", id: tceInstance.id);
        }
    };


    /*
     * Closure que exibe um previews do tce.
     */
    def show   = {
        if (!verificaLogon()) {
            return;
        }
        def tceInstance = Tce.findById(params.id);
        // REMUNERAÇÃO.
        // Carrega as remunerações cadastrados.
        def tceRemuneraInstance   = TceRemunera.findAllByTce(tceInstance);
        // PAGAMENTO.
        // Carrega os pagamentos cadastrados.
        def tcePagamentoInstance   = TcePagamento.findAllByTce(tceInstance);
        // FORMA PAGAMENTO
        def formaPagamentoInstance = FormaPagamento.findAll();
        // PLANO DE ESTÁGIO.
        // Carrega os planos cadastrados.
        def planoEstagioInstance   = PlanoEstagio.findAllByTce(tceInstance);
        //envia os dados para tela.
        if (tceInstance){
            return [tceInstance              : tceInstance,
                    tceRemuneraInstanceList  : tceRemuneraInstance,
                    tcePagamentoInstanceList : tcePagamentoInstance,
                    planoEstagioInstanceList : planoEstagioInstance]
        }else {
            flash.message="TCE não encontrado!";
            redirect(action: "list");
        }

    };


    /*
     * Closure responsável por gerar o tce, ou seja, trocar o status para liberado.
     */
    def gerarTce = {
        Tce tce = Tce.findById(params.id);
        if(tceService.verificaPendenciasTce(tce)){
            tce.situacao = 1;
            tce.properties = tce;
            if(tce.save()){
                flash.message = "TCE gerado com sucesso.";
                redirect(action:'list');
            }else{
                flash.message = "Não foi possível gerar o TCE.";
                redirect(action:'edit', id:tce);
            }
        }else{
            flash.message = "Não foi possível gerar o TCE. Possíveis causas:<br/>- Não possui Remuneração cadastrada;<br/>- Não possui plano de estágio ou não tem as assinaturas.";
            redirect(action:'edit', id:tce);
        }

    }

    /*
     * Closure responsável por recindir um TCE.
     */
    def rescindirTce = {
        def tceInstance = Tce.get(params.id);
        if(params.dtRescisao && params.rescCausa){
            //params.situacao = 3;
            tceInstance.properties = params;

            println(params);

            if(tceInstance.save()){
                flash.message = "TCE rescindido com sucesso.";
                redirect(action:'edit', id:params.id);
            }else{
                flash.message = "Não foi possível rescindir o TCE.";
                redirect(action:'edit', id:params.id);
            }
        }else{
            flash.message = "Não foi possível rescindir o TCE.<br/> É obrigatório informar a data e a causa da rescisão.";
            redirect(action:'edit', id:params.id);
        }

    }


    /*
     * Método que verifica se o usuário está logado.
     * Se não estiver logado é redirecionado para home
     */
    private boolean verificaLogon() {
        if(!session["pessoa"]){
            flash.message = "Você precisa estar logado para acessar esta página.";
            redirect(controller:'login', action:'auth');
            return false;
        }

        return true;
    }
    
}
